package cn.edu.swu.hh;

import java.io.*; //输入输出流
import java.net.HttpURLConnection; //处理HTTP连接
import java.net.URL; //处理URL
import java.nio.charset.StandardCharsets; //UTF-8编码
import java.nio.file.*; //文件系统操作

public class FileUtils {
    public static String saveImage(String urlStr,String savePath) {
        HttpURLConnection connection = null; //网络连接对象
        InputStream inputStream = null; //输入流（从网络读取数据）
        OutputStream outputStream = null; //输出流（往本地文件写数据）
        try {
            // 1.打开网络连接
            URL url = new URL(urlStr);
            connection = (HttpURLConnection) url.openConnection();

            //设置一些参数避免被网站拒绝
            connection.setInstanceFollowRedirects(true); //支持重新定向
            connection.setConnectTimeout(15000); //连接超时15s
            connection.setReadTimeout(30000); //读取超时30s
            connection.connect(); //发送请求

            //2.检查响应状态码
            int code = connection.getResponseCode();
            if (code / 100 == 3) { //如果是3xx，说明被重新定向
                String loc = connection.getHeaderField("Location");
                if (loc != null && !loc.isEmpty()) {
                    //递归调用自己，继续下载新地址
                    return saveImage(loc,savePath);
                }
            }
            if (code != HttpURLConnection.HTTP_OK) {
                //如果不是2xx，说明请求失败
                System.out.println("HTTP响应异常：" + code);
                return null;
            }

            //3.开始读取数据（输入流）
            inputStream = connection.getInputStream();

            //4.确保保存目录存在
            Path target = Paths.get(savePath);
            ensureDirectoryExists(target.getParent().toString());

            //5.打开输出流，准备写入本地文件
            outputStream = Files.newOutputStream(target,StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING); //如果文件不存在则创建，如果存在则覆盖

            //6.使用8KB缓冲区进行读写
            byte[] buffer = new byte[8192];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer,0,length);
            }

            //7.强制写入磁盘
            outputStream.flush();
            //返回文件的绝对路径
            return target.toAbsolutePath().toString();
        }catch (Exception e) { //处理其他可能的异常，避免程序崩溃
            System.out.println("下载出错：" + e.getMessage());
            return null;
        }finally {
            //8.释放资源（无论成功还是失败都执行）
            try {
                if (outputStream != null)
                    outputStream.close();
            }catch (IOException ignored) {}
            try {
                if (inputStream != null)
                    inputStream.close();
            }catch (IOException ignored) {}
            if (connection != null)
                connection.disconnect();
        }
    }

    //确保目录存在，如果不存在则创建（目录路径：dirPath）
    public static void ensureDirectoryExists(String dirPath) {
        if (dirPath == null || dirPath.isEmpty())
            return;
        try {
            Path dir = Paths.get(dirPath);
            if (!Files.exists(dir)) {
                Files.createDirectories(dir); // 创建多级目录
            }
        }catch (IOException e) { //专门处理I/O错误
            System.out.println("创建目录失败：" + e.getMessage());
        }
    }

    //追加日志到文件（日志文件路径：logFile 要追加的内容：line）
    public static void appendLog(String logFILE,String line) {
        try {
            Path logPath = Paths.get(logFILE);
            if (!Files.exists(logPath)) {
                Files.createDirectories(logPath);
            }
            //写入文件（追加模式）
            Files.write(logPath,(line + System.lineSeparator()).getBytes(StandardCharsets.UTF_8),StandardOpenOption.APPEND);
        }catch (IOException e) {
            System.out.println("写入日志失败：" + e.getMessage());
        }
        }
    }

